// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (c) 2004-2011, International Business Machines
 * Corporation and others.  All Rights Reserved.
 * Copyright (C) 2010 , Yahoo! Inc.
 *******************************************************************************
 */
package com.ibm.icu.dev.test.format;

import com.ibm.icu.dev.test.CoreTestFmwk;
import com.ibm.icu.text.SelectFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * @author kirtig This class tests the API functionality of the SelectFormat
 */
@RunWith(JUnit4.class)
public class SelectFormatAPITest extends CoreTestFmwk {

    static final String SIMPLE_PATTERN1 = "feminine {feminineVerbValue1} other{otherVerbValue1}";
    static final String SIMPLE_PATTERN2 = "feminine {feminineVerbValue2} other{otherVerbValue2}";

    /** API tests for constructors */
    @Test
    public void TestConstructors() {
        SelectFormat selFmt = new SelectFormat(SIMPLE_PATTERN1);
        assertNotNull(
                "Error: TestConstructors - SelectFormat object constructed "
                        + "with argument constructor is null",
                selFmt);
    }

    /** API tests for equals() method */
    @Test
    public void TestEquals() {
        SelectFormat selFmt1 = null;

        // Check equality for pattern constructed SelectFormats
        selFmt1 = new SelectFormat(SIMPLE_PATTERN1);
        SelectFormat selFmt2 = new SelectFormat(SIMPLE_PATTERN1);
        assertTrue(
                "Equals test failed while checking equality for "
                        + "pattern constructed SelectFormats .",
                selFmt1.equals(selFmt2));

        // Check equality for 2 objects
        Object selFmt3 = new SelectFormat(SIMPLE_PATTERN1);
        Object selFmt4 = new SelectFormat(SIMPLE_PATTERN1);
        Object selFmt5 = new SelectFormat(SIMPLE_PATTERN2);
        assertTrue(
                "Equals test failed while checking equality for object 1.",
                selFmt3.equals(selFmt4));
        assertTrue(
                "Equals test failed while checking equality for object 2.",
                selFmt1.equals(selFmt3));
        assertFalse(
                "Equals test failed while checking equality for object 3.",
                selFmt3.equals(selFmt5));
    }

    /** API tests for applyPattern() method */
    @Test
    public void TestApplyPatternToPattern() {
        SelectFormat selFmt = null;
        String pattern = "masculine{masculineVerbValue} other{otherVerbValue}";

        // Check for applyPattern/toPattern
        selFmt = new SelectFormat(SIMPLE_PATTERN1);
        selFmt.applyPattern(pattern);
        assertEquals(
                "Failed in applyPattern,toPattern with unexpected output",
                pattern,
                selFmt.toPattern());

        // Check for invalid pattern
        try {
            String brokenPattern = "broken }{ pattern";
            selFmt.applyPattern(brokenPattern);
            errln(
                    "Failed in applyPattern.  applyPattern should throw IllegalArgumentException for "
                            + brokenPattern);
        } catch (IllegalArgumentException e) {
            // This is OK
        }
    }

    /** API tests for toString() method */
    @Test
    public void TestToString() {
        SelectFormat selFmt = null;

        // Check toString for pattern constructed SelectFormat
        selFmt = new SelectFormat(SIMPLE_PATTERN1);
        String expected = "pattern='feminine {feminineVerbValue1} other{otherVerbValue1}'";
        assertEquals(
                "Failed in TestToString with unexpected output 2", expected, selFmt.toString());
    }

    /** API tests for hashCode() method */
    @Test
    public void TestHashCode() {
        // Check hashCode for pattern constructed SelectFormat
        SelectFormat selFmt = new SelectFormat(SIMPLE_PATTERN1);
        SelectFormat selFmt1 = new SelectFormat(SIMPLE_PATTERN1);
        SelectFormat selFmt2 = new SelectFormat(SIMPLE_PATTERN2);
        assertEquals(
                "Failed in TestHashCode 1 with unexpected output",
                selFmt.hashCode(),
                selFmt1.hashCode());
        assertNotEquals(
                "Failed in TestHashCode 2 with unexpected output",
                selFmt.hashCode(),
                selFmt2.hashCode());
    }

    /** API tests for toPattern() method */
    @Test
    public void TestToPattern() {
        SelectFormat selFmt = new SelectFormat(SIMPLE_PATTERN1);
        assertEquals(
                "Failed in TestToPattern 2 with unexpected output",
                SIMPLE_PATTERN1,
                selFmt.toPattern());
    }

    /** API tests for format() method */
    @Test
    public void TestFormat() {
        // Check format for pattern constructed object
        SelectFormat selFmt1 = new SelectFormat(SIMPLE_PATTERN1);
        String expected = "feminineVerbValue1";
        assertEquals(
                "Failed in TestFormat with unexpected output 1",
                expected,
                selFmt1.format("feminine"));

        // Check format with appendTo for pattern constructed object
        expected = "AppendHere-otherVerbValue1";
        StringBuffer strBuf = new StringBuffer("AppendHere-");
        assertEquals(
                "Failed in TestFormat with unexpected output 2",
                expected,
                (selFmt1.format("other", strBuf, new FieldPosition(0))).toString());

        // Check format throws exception on invalid argument.
        boolean threwException = false;
        try {
            StringBuffer buf = new StringBuffer("AppendHere-");
            selFmt1.format(0, buf, new FieldPosition(0));
        } catch (IllegalArgumentException e) {
            threwException = true;
        }
        assertTrue("Did not throw IllegalArgumentException.", threwException);
    }

    /** API tests for parseObject() method */
    @Test
    public void TestParseObject() {
        // Check parseObject
        try {
            SelectFormat selFmt = new SelectFormat(SIMPLE_PATTERN1);
            selFmt.parseObject("feminine", new ParsePosition(0));
            fail("Failed in TestParseObject - UnsupportedOperationException not received");
        } catch (UnsupportedOperationException e) {
            // Expect this Exception
        }
    }
}
